package org.adorsys.aderp.aderplogin.client.hessian;

import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.adorsys.aderp.aderplogin.client.common.Oauth2User;
import org.adorsys.aderp.aderplogin.client.common.Oauth2UserCache;
import org.adorsys.aderp.aderplogin.client.common.Oauth2UserProvider;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;

/**
 * Retrieve token from cookie, load {@link Oauth2User}, store in a
 * Session and return it.
 * 
 * 
 * 
 * @author francis
 *
 */
public class HTTPSessionBasedOauth2UserCache implements InitializingBean, Oauth2UserCache {

	// initialized in afterPropertiesDet
	private String cookieTokenName;
	private Oauth2UserProvider oauth2UserProvider;

	@Override
	public Oauth2User retrieveAndStoreTokenFilter(ServletRequest servletRequest) {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		
		Oauth2User user = (Oauth2User) request.getSession(true).getAttribute(cookieTokenName);
		if(user==null){
			String accessToken = extractMainCookie(request);
			if(accessToken==null){
				throw new IllegalStateException("Missing access token");
			}			
			user = oauth2UserProvider.getUser(accessToken);
			if(user==null){
				throw new IllegalStateException("Invalid access token");
			}
		}
		request.getSession(true).setAttribute(cookieTokenName, user);
		
		return user;
	}


    protected String extractMainCookie(HttpServletRequest request) {
    	Cookie[] cookies = request.getCookies();
    	if(cookies==null) return null;
    	for (Cookie cookie : cookies) {
    		if(StringUtils.equals(cookieTokenName, cookie.getName()))
    			return cookie.getValue();
		}
    	return null;
    }

	public void setCookieTokenName(String cookieTokenName) {
		this.cookieTokenName = cookieTokenName;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if(oauth2UserProvider==null) throw new IllegalStateException("Oauth2UserProvider must be set");
		if(cookieTokenName==null) throw new IllegalStateException("cookieTokenName must be set");
	}


	public void setOauth2UserProvider(Oauth2UserProvider oauth2UserProvider) {
		this.oauth2UserProvider = oauth2UserProvider;
	}
	
}
